home *** CD-ROM | disk | FTP | other *** search
- /*
- ** HUGEREAD.C - "Universal" PC read and write functions using huge data
- ** and far pointers.
- **
- ** public domain by Bob Stout
- **
- ** NOTES:
- **
- ** 1. If these functions are called with a prototype in scope, passed
- ** parameters will be coerced to the proper data types.
- **
- ** 2. Since these call read() and write(), all normal mode flags which
- ** are supported by individual compilers will be honored.
- **
- ** 3. In small data memory models (S, T, and M), an intermediate buffer
- ** is allocated and used. In large data models (L and C), the data
- ** are read/written directly from/to target memory.
- */
-
- #include <dos.h>
- #include <io.h>
- #include <stdlib.h>
- #include <stddef.h>
-
- #ifndef min
- #define min(x,y) (((x) <= (y)) ? (x) : (y))
- #endif
-
- #ifndef MK_FP
- #define MK_FP(seg,offset) \
- ((void _far *)(((unsigned long)(seg)<<16) | (unsigned)(offset)))
- #endif
-
- /*
- ** Get the largest buffer possible.
- */
-
- static size_t gettmp(char **buf)
- {
- static size_t bufsiz = 0;
- static char *buffer = NULL;
-
- if (bufsiz)
- {
- *buf = buffer;
- return bufsiz;
- }
- for (bufsiz = 0x4000; bufsiz >= 128; bufsiz >>= 1)
- {
- if (NULL != (buffer = (char *) malloc(bufsiz)))
- {
- *buf = buffer;
- return bufsiz;
- }
- }
- return 0;
- }
-
- /*
- ** Normalize a far pointer
- */
-
- void _far *farnormal(void _far *ptr)
- {
- size_t seg, ofs;
-
- seg = FP_SEG(ptr);
- ofs = FP_OFF(ptr);
- return MK_FP(seg + (ofs >> 4), ofs & 0xf);
- }
-
- /*
- ** Read any size block to anywhere in memory
- */
-
- long hugeread(int fh, char _far *buf, long size)
- {
- long count;
- size_t bufsiz;
- char *tmp;
- long ercode = size;
-
- if (4 > sizeof(void *))
- {
- if (0 == (bufsiz = gettmp(&tmp)))
- return -1L;
- }
- else
- {
- tmp = (char *)buf;
- bufsiz = 0x4000;
- }
-
- while (0 < (count = min(size, (long)bufsiz)))
- {
- int i, numread = read(fh, tmp, (size_t)count);
-
- if (1 > numread || numread != (int)count)
- return -1L;
- if (4 > sizeof(void *))
- {
- for (i = count; i; --i)
- buf[i] = tmp[i];
- }
- buf = farnormal(buf + count);
- size -= count;
- if (2 < sizeof(void *))
- tmp = (char *)buf;
- }
- return ercode;
- }
-
- /*
- ** Write any size block from anywhere in memory
- */
-
- long hugewrite(int fh, char _far *buf, long size)
- {
- long count;
- size_t bufsiz;
- char *tmp;
- long ercode = size;
-
- if (4 > sizeof(void *))
- {
- if (0 == (bufsiz = gettmp(&tmp)))
- return -1L;
- }
- else
- {
- tmp = (char *)buf;
- bufsiz = 0x4000;
- }
-
- while (0 < (count = min(size, (long)bufsiz)))
- {
- int i, numwrite;
-
- if (4 > sizeof(void *))
- {
- for (i = count; i; --i)
- tmp[i] = buf[i];
- }
- numwrite = write(fh, tmp, (size_t)count);
- if (1 > numwrite || numwrite != (int)count)
- return -1L;
- buf = farnormal(buf + count);
- size -= count;
- if (2 < sizeof(void *))
- tmp = (char *)buf;
- }
- return ercode;
- }
-